
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>JVM内存模型 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>JVM内存模型 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">JVM内存模型（JMM）旨在实现哪三个主要目标？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JVM内存模型（JMM）的三个主要目标是：1. 线程安全性，确保多线程程序中的数据一致性；2. 跨平台性，屏蔽底层硬件和操作系统的差异，让Java程序表现一致；3. 高效性，通过优化和重排序提升程序运行效率，同时维持正确性。</div>
          </div>
          <div class="card-source">来源: JVM内存模型概述 -> JVM内存模型的目标</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">概念</div>
          <div class="card-question">JVM运行时数据区中，哪些是线程私有的，哪些是线程共享的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">概念</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">线程私有的区域包括：程序计数器、Java虚拟机栈和本地方法栈。线程共享的区域包括：堆（Heap）和方法区（在JDK 8后实现为元空间）。</div>
          </div>
          <div class="card-source">来源: JVM内存区域划分 -> 1. 线程私有区域, 2. 线程共享区域</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在多线程编程中，JMM通过哪三个核心特性来保证程序的正确执行？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">JMM提供了三个核心保证：1. 可见性，确保一个线程对共享变量的修改能被其他线程及时看到；2. 有序性，通过happens-before规则等机制保证指令执行顺序符合程序语义；3. 原子性，保证基本操作（如赋值）在执行过程中不会被线程中断。</div>
          </div>
          <div class="card-source">来源: JVM内存模型概述 -> 内存模型与多线程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">结构</div>
          <div class="card-question">Java堆内存（Heap）通常被细分为哪两个主要部分？它们各自的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">结构</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">堆内存主要划分为新生代（Young Generation）和老年代（Old Generation）。新生代主要用于存放生命周期较短的对象，垃圾回收频繁（Minor GC）；老年代则用于存放生命周期较长或从新生代晋升的对象，垃圾回收频率较低（Major GC / Full GC）。</div>
          </div>
          <div class="card-source">来源: 堆内存细化 -> 1. 堆内存的整体划分</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">流程</div>
          <div class="card-question">一个对象从新生代晋升到老年代通常需要满足什么条件？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">流程</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">对象从新生代晋升到老年代的条件主要有两个：1. 对象的年龄（即在Survivor区存活的次数）达到某个阈值（默认为15次）；2. 在进行Minor GC后，Survivor区无法容纳所有存活的对象，此时部分对象会直接晋升到老年代。</div>
          </div>
          <div class="card-source">来源: 堆内存细化 -> 3. 老年代的细化结构</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">自JDK 8起，JVM的方法区在实现上发生了什么重要变化？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">自JDK 8起，方法区的实现由永久代（PermGen）被替换为了元空间（Metaspace）。与永久代不同，元空间不再是JVM堆的一部分，而是存储在本地内存（直接内存）中，从而不再受堆内存大小的限制。</div>
          </div>
          <div class="card-source">来源: 堆内存细化 -> 4. 元空间（Metaspace，JDK 8及以上）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">什么是类加载的双亲委派机制？它有什么好处？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">双亲委派机制是指当一个类加载器收到类加载请求时，它首先不会自己去尝试加载，而是把这个请求委派给父类加载器去完成。只有当父加载器无法完成加载时，子加载器才会尝试自己加载。这样做的好处是：1. 避免类的重复加载；2. 确保核心类库的安全性，防止核心API被篡改。</div>
          </div>
          <div class="card-source">来源: 类加载与方法区 -> 1.3 类加载的双亲委派机制</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">概念</div>
          <div class="card-question">什么是直接内存（Direct Memory）？它相比堆内存有什么优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">概念</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">直接内存是由操作系统直接分配和管理的内存区域，不受Java堆管理。它可以通过NIO的`ByteBuffer.allocateDirect()`方法使用。其主要优势在于：1. 提高I/O性能，减少了数据在JVM堆和操作系统之间的复制；2. 减少GC开销，因为它不受JVM垃圾回收器的影响。</div>
          </div>
          <div class="card-source">来源: 直接内存（Direct Memory） -> 1. 直接内存的特点 & 4. 直接内存的优势与应用场景</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">问题</div>
          <div class="card-question">当一个方法被无限递归调用时，最可能导致哪种JVM错误？可以通过哪个参数进行调整？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">问题</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当方法递归调用过深，导致栈帧数量超过JVM栈的最大深度时，会抛出 `StackOverflowError` 错误。可以通过JVM参数 `-Xss` 来调整每个线程的栈大小。</div>
          </div>
          <div class="card-source">来源: JVM栈与线程内存 -> 5.1 栈溢出（StackOverflowError）</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
